package com.walter.blog.exception;

import com.walter.response.ResponseKit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.net.SocketTimeoutException;

/**
 * 异常处理
 *
 * @author 1126
 */
@Slf4j
@ControllerAdvice
public class CatchException {

    /**
     * 拦截未知异常
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public ResponseKit<Object> unknownException(Exception e) {
        log.error("系统异常：", e);
        return ResponseKit.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), "系统异常");
    }

    /**
     * 拦截参数校验异常
     */
    @ExceptionHandler(value = {BindException.class, MethodArgumentNotValidException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public ResponseKit<Object> bindException(Exception e) {
        BindingResult bindResult = null;
        if (e instanceof BindException) {
            bindResult = ((BindException) e).getBindingResult();
        } else if (e instanceof MethodArgumentNotValidException) {
            bindResult = ((MethodArgumentNotValidException) e).getBindingResult();
        }

        if (bindResult != null && bindResult.hasErrors()) {
            return ResponseKit.error(HttpStatus.BAD_REQUEST.value(), bindResult.getAllErrors().get(0).getDefaultMessage());

        }

        log.error("参数校验异常：", e);
        return ResponseKit.error(HttpStatus.BAD_REQUEST.value(), "参数异常");
    }

    /**
     * 拦截请求超时异常
     */
    @ExceptionHandler(SocketTimeoutException.class)
    @ResponseStatus(HttpStatus.REQUEST_TIMEOUT)
    @ResponseBody
    public ResponseKit<String> requestTimeOutException() {
        log.error("请求超时！");
        return ResponseKit.error(HttpStatus.REQUEST_TIMEOUT.value(), "请求超时，请稍后重试！");
    }

    @ExceptionHandler(AccessDeniedException.class)
    @ResponseStatus(HttpStatus.FORBIDDEN)
    @ResponseBody
    public ResponseKit<String> accessDeniedException() {
        log.error("权限异常");
        return ResponseKit.error(HttpStatus.FORBIDDEN.value(), "权限异常");
    }

}
